package com.itcam.daijia.map.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.itcam.daijia.common.execption.NGException;
import com.itcam.daijia.common.result.ResultCodeEnum;
import com.itcam.daijia.map.service.MapService;
import com.itcam.daijia.model.form.map.CalculateDrivingLineForm;
import com.itcam.daijia.model.vo.map.DrivingLineVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Service
@SuppressWarnings({"unchecked", "rawtypes"})
public class MapServiceImpl implements MapService {

    @Autowired
    private RestTemplate restTemplate;

    @Value("${tencent.map.key}")
    private String key; // 腾讯地图服务

    /**
     * 计算驾驶线路
     * @param calculateDrivingLineForm 包含起点和终点经纬度的表单
     * @return 返回驾驶线路的相关信息，包括距离、预估时间和路线坐标点串
     */
    @Override
    public DrivingLineVo calculateDrivingLine(CalculateDrivingLineForm calculateDrivingLineForm) {
        // 请求腾讯提供的接口，按照接口要求传递相关参数，返回需要结果
        // 使用HttpClient，目前Spring封装调用工具使用RestTemplate
        // 1.定义调用腾讯地址
        String url = "https://apis.map.qq.com/ws/direction/v1/driving/?from={from}&to={to}&key={key}";

        // 2.封装传递的参数
        HashMap<String, String> map = new HashMap<>();
        map.put("key", key);
        map.put("from", calculateDrivingLineForm.getStartPointLatitude() + "," + calculateDrivingLineForm.getStartPointLongitude());
        map.put("to", calculateDrivingLineForm.getEndPointLatitude() + "," + calculateDrivingLineForm.getEndPointLongitude());

        // 3.发送GET请求到腾讯地图API，并获取返回的JSON结果
        JSONObject result = restTemplate.getForObject(url, JSONObject.class, map);

        // 4.处理返回结果
        // 判断调用是否成功
        int status = result.getIntValue("status");
        if (status != 0) {
            // 如果调用失败，抛出异常
            throw new NGException(ResultCodeEnum.MAP_FAIL);
        }

        // 返回路线的相关信息
        JSONObject route = result.getJSONObject("result").getJSONArray("routers").getJSONObject(0);

        // 5.创建一个vo对象，用于封装返回的路线信息
        DrivingLineVo drivingLineVo = new DrivingLineVo();
        // 路线总距离（把米转换为千米，然后小数点保留2位） 6.583 ~ 6.59
        drivingLineVo.setDistance(route.getBigDecimal("distance").divide(new BigDecimal(1000), 2, RoundingMode.HALF_UP));
        // 预估时间
        drivingLineVo.setDuration(route.getBigDecimal("duration"));
        // 路线坐标点串
        drivingLineVo.setPolyline(route.getJSONArray("polyline"));

        // 6.返回封装好的路线信息对象
        return drivingLineVo;
    }

}
